/**
 * The Free Gaming System; main engine handling functions.
 *
 * Copyright 2006 the Free Gaming System developers.
 *
 * FGS is the legal property of its developers, whose names are too
 * numerous to list here.  Please refer to the COPYRIGHT file
 * distributed with this source distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 */

#include <stdlib.h>
#include "fgs_game.h"
#include "fgs_internal.h"

fgs_error_t
fgs_init(fgs_ctx_t **ctx, const char *name, const char *version,
         int server_port, fgs_callbacks_t *cb_table)
{
  fgs_error_t err;

  /* Validate the first parameters */
  if (ctx == NULL || name == NULL ||
      version == NULL || server_port < 1 ||
      cb_table == NULL)
    return FGS_ERR_INVALID_PARAMS;

  /* Validate the callback table */
  FGS_ERR(fgs__callbacks_validate(cb_table));

  /* Build the context */
  *ctx = fgs__alloc(1, sizeof(**ctx));
  (*ctx)->cb_table = cb_table;

  /* Initially, no players recorded. */
  (*ctx)->n_players = 0;
  (*ctx)->players = NULL;

  /* Connect to the proxy and register */
  err = fgs__proxy_connect(*ctx, name, version, server_port);
  if (err != FGS_OK)
    {
      fgs__free(*ctx);
      return err;
    }

  return FGS_OK;
}


fgs_error_t
fgs_shutdown(fgs_ctx_t *ctx)
{
  int i;

  if (ctx == NULL)
    return FGS_ERR_INVALID_PARAMS;

  FGS_ERR(fgs__proxy_disconnect(ctx));

  /* Destroy the player lookup table */
  for (i = 0; i < ctx->n_players; i++)
    fgs__free(ctx->players[i].uuid);
  if (ctx->players != NULL)
    fgs__free(ctx->players);

  /* Destroy the callbacks table and the context. */
  fgs__free(ctx->cb_table);
  fgs__free(ctx);

  return FGS_OK;
}


fgs_error_t
fgs_process_config(fgs_ctx_t *ctx)
{
  if (ctx == NULL)
    return FGS_ERR_INVALID_PARAMS;

  /* No configuration callback defined means the host server can't
   * process any extra configuration directives.  It is not an error,
   * so we should just return and be done with it.
   */
  if (ctx->cb_table->append_config == NULL)
    return FGS_OK;

  /* Otherwise, loop and retrieve all values the proxy is willing to
   * give us.
   */
  while (1)
    {
      char *k, *v;

      FGS_ERR(fgs__proxy_get_config(ctx, &k, &v));

      if (k == NULL)
        return FGS_OK;

      /* Call the config callback with the values. */
      ctx->cb_table->append_config(k, v);
      fgs__free(k);
      fgs__free(v);
    }
}
